//! @Author: DengLibin 榆霖
//! @Date:  2022-07-06 16:06:15
//! @Description: 文件上传

use std::{io::Write, fs::{self}};


use actix_multipart::Multipart;
use actix_web::{ get,
    http::header::{ ContentType,
    },
    post,
    web::{self},
    Error, HttpResponse, Scope,
};

use common::pojo::ResData;
use futures_util::TryStreamExt;
use uuid::Uuid;

use crate::sys::init;

/// @Author: DengLibin 榆霖
/// @Date:  2022-07-06 16:08:47
/// @Description: 路由配置
pub fn route() -> Scope {
    info!("file_controller配置路由");
    let sys_scope = web::scope("/file");
    sys_scope.service(upload)
             .service(down)
}
#[post("upload")]
async fn upload(mut payload: Multipart) -> Result<HttpResponse, Error> {
    // iterate over multipart stream
    while let Some(mut field) = payload.try_next().await? {
        // A multipart/form-data stream has to contain `content_disposition`
        let content_disposition = field.content_disposition();

        let filename = content_disposition
            .get_filename()
            .map_or_else(|| Uuid::new_v4().to_string(), sanitize_filename::sanitize);
        let filepath = format!("{}/{}", init::TEMP_DIR, filename);

        // File::create is blocking operation, use threadpool
        let mut f = web::block(|| std::fs::File::create(filepath)).await??;

        // Field in turn is stream of *Bytes* object
        while let Some(chunk) = field.try_next().await? {
            // filesystem operations are blocking, we have to use threadpool
            f = web::block(move || f.write_all(&chunk).map(|_| f)).await??;
        }
    }

    Ok(HttpResponse::Ok().json(ResData::success("")))
}
/// @Author: DengLibin 榆霖
/// @Date:  2022-07-07 11:39:55
/// @Description: 文件下载
#[get("down/{name}")]
async fn down(path: web::Path<(String,)>) -> Result<HttpResponse, Error> {
    let (file_name,) = path.into_inner();
    let file_path = format!("{}/{}", init::TEMP_DIR, file_name);

    let mut builder = HttpResponse::Ok();

    
    builder.content_type(ContentType::octet_stream());
    builder.append_header((actix_web::http::header::CONTENT_DISPOSITION, format!("attachment; filename={}", file_name)));


    Ok(builder.body(fs::read_to_string(file_path).unwrap()))
}
